using System;
using Server;	
using Server.Items;
using Server.Mobiles;
using Server.Network;
using System.Linq;
using Server.Gumps;

namespace Server.Engines.Shadowguard
{
	public class ShadowguardBottleOfLiquor : BaseDecayingItem
	{
		public override int Lifespan { get { return 60; } }
		public override int LabelNumber { get { return 1042961;  } } // a bottle of liquor
		
        public BarEncounter Encounter { get; set; }

		[Constructable]
		public ShadowguardBottleOfLiquor(BarEncounter encounter) : base(0x99B)
		{
            Encounter = encounter;
		}
		
		public override void OnDoubleClick(Mobile m)
		{
			if(m.InRange(this.GetWorldLocation(), 2))
			{
				if(0.1 > Utility.RandomDouble())
				{
					m.BAC = Math.Min(60, m.BAC + 10);
					m.PlaySound( Utility.RandomList( 0x30, 0x2D6 ) );
					BaseBeverage.CheckHeaveTimer(m);
					
					m.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1156270, m.NetState); // *You ready the bottle to throw but it's enchanting label persuades you to drink it instead!*
					
					Delete();
				}
				else
				{
					m.SendLocalizedMessage(1010086); // What do you want to use this on?
					m.BeginTarget(10, false, Server.Targeting.TargetFlags.None, (from, targeted) =>
					{
						if(0.25 > Utility.RandomDouble() && m.BAC > 0)
						{
							AOS.Damage(m, Utility.RandomMinMax( 25, 50 ), 100, 0, 0, 0, 0 );
							m.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1156271, m.NetState); // *You wind up to throw but in your inebriated state you manage to hit yourself!*
                            m.FixedParticles(0x3728, 20, 10, 5044, EffectLayer.Head);

							Delete();
						}
						else if (targeted is ShadowguardPirate)
						{
							ShadowguardPirate pirate = targeted as ShadowguardPirate;
							
							m.DoHarmful( pirate );
							m.MovingParticles( pirate, 0x99B, 10, 0, false, true, 0, 0, 9502, 6014, 0x11D, EffectLayer.Waist, 0 );
							
							Timer.DelayCall(TimeSpan.FromSeconds(.5), () =>
							{
                                if (pirate.Alive)
                                {
                                    // this is gay, but can't figure out a better way to do!
                                    pirate.BlockReflect = true;
                                    AOS.Damage(pirate, m, 300, 0, 0, 0, 0, 0, 0, 100);
                                    pirate.BlockReflect = false;
                                    pirate.FixedParticles(0x3728, 20, 10, 5044, EffectLayer.Head);

                                    pirate.PlaySound(Utility.Random(0x3E, 3));
                                }
							});
							
							Delete();
						}
						else
							m.SendLocalizedMessage(1156211); // You cannot throw this there!
					});
				}
			}
		}

        public override void OnAfterDelete()
        {
            if (Encounter != null)
                Encounter.CheckEncounter();
        }
		
		public ShadowguardBottleOfLiquor(Serial serial) : base(serial)
		{
		}
		
		public override void Serialize(GenericWriter writer)
		{
			base.Serialize(writer);
			writer.Write(0);
		}
		
		public override void Deserialize(GenericReader reader)
		{
			base.Deserialize(reader);
			int version = reader.ReadInt();
		}
	}
	
	public enum VirtueType 
	{
		Honesty,
		Compassion,
		Valor,
		Justice,
		Sacrafice,
		Honor,
		Spirituality,
		Humility,				
		Deceit,
		Despise,
		Destard,
		Wrong,
		Covetous,
		Shame,
		Hythloth,
		Pride
	}
	
	public class ShadowguardApple : BaseDecayingItem
	{
		[CommandProperty(AccessLevel.GameMaster)]
		public ShadowguardCypress Tree { get; set; }
	
		[CommandProperty(AccessLevel.GameMaster)]
		public OrchardEncounter Encounter { get; set; }
		
		public override int Lifespan { get { return 60; } }
	
		public ShadowguardApple(OrchardEncounter encounter, ShadowguardCypress tree) : base(0x9D0)
		{
			Encounter = encounter;
			Tree = tree;
		}
		
		public override void AddNameProperty( ObjectPropertyList list )
		{
            if(Tree != null)
			    list.Add(1156210, Tree.VirtueType.ToString()); // An Enchanted Apple of ~1_TYPE~
		}
	
		public override void OnDoubleClick(Mobile m)
		{
			if(IsChildOf(m.Backpack) && Tree != null)
			{
				m.SendLocalizedMessage(1010086); // What do you want to use this on?
				m.BeginTarget(10, false, Server.Targeting.TargetFlags.None, (from, targeted) =>
				{
                    if (targeted is ShadowguardCypress || targeted is ShadowguardCypress.ShadowguardCypressFoilage)
                    {
                        ShadowguardCypress tree = null;

                        if (targeted is ShadowguardCypress)
                            tree = targeted as ShadowguardCypress;
                        else if (targeted is ShadowguardCypress.ShadowguardCypressFoilage)
                            tree = ((ShadowguardCypress.ShadowguardCypressFoilage)targeted).Tree;

                        if (tree != null)
                        {
                            Point3D p = tree.Location;
                            Map map = tree.Map;

                            from.Animate(31, 7, 1, true, false, 0);
                            m.MovingParticles(tree, this.ItemID, 10, 0, false, true, 0, 0, 9502, 6014, 0x11D, EffectLayer.Waist, 0);

                            Timer.DelayCall(TimeSpan.FromSeconds(.7), () =>
                                {
                                    if (tree.IsOppositeVirtue(Tree.VirtueType))
                                    {
                                        tree.Delete();

                                        Effects.SendLocationParticles(EffectItem.Create(p, map, EffectItem.DefaultDuration), 0x3709, 10, 30, 5052);
                                        Effects.PlaySound(p, map, 0x243);

                                        m.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1156213, m.NetState); // *Your throw releases powerful magics and destroys the tree!*

                                        if (Tree != null)
                                        {
                                            p = Tree.Location;
                                            Tree.Delete();

                                            Effects.SendLocationParticles(EffectItem.Create(p, map, EffectItem.DefaultDuration), 0x3709, 10, 30, 5052);
                                            Effects.PlaySound(p, map, 0x243); //TODO: Get sound
                                        }

                                        tree.Encounter.CheckEncounter();
                                        Delete();
                                    }
                                    else
                                    {
                                        p = m.Location;
                                        var creature = new VileTreefellow();

                                        for (int i = 0; i < 10; i++)
                                        {
                                            int x = Utility.RandomMinMax(p.X - 1, p.X + 1);
                                            int y = Utility.RandomMinMax(p.Y - 1, p.Y + 1);
                                            int z = p.Z;

                                            if (map.CanSpawnMobile(x, y, z))
                                            {
                                                p = new Point3D(x, y, z);
                                                break;
                                            }
                                        }

                                        creature.MoveToWorld(p, map);
                                        creature.Combatant = m;
                                        m.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1156212, m.NetState); // *Your throw seems to have summoned an ambush!*

                                        if (Encounter is OrchardEncounter)
                                            ((OrchardEncounter)Encounter).AddSpawn(creature);

                                        Delete();
                                    }
                                });
                        }
                    }
				});
			}
		}

        public override void Delete()
        {
            base.Delete();

            if (Encounter != null)
            {
                Encounter.OnAppleDeleted();
            }
        }

		public ShadowguardApple(Serial serial) : base(serial)
		{
		}
		
		public override void Serialize(GenericWriter writer)
		{
			base.Serialize(writer);
			writer.Write(0);
			
			writer.Write(Tree);
		}
		
		public override void Deserialize(GenericReader reader)
		{
			base.Deserialize(reader);
			int version = reader.ReadInt();
			
			Tree = reader.ReadItem() as ShadowguardCypress;
		}
	}
	
	public class ShadowguardCypress : Item
	{
		[CommandProperty(AccessLevel.GameMaster)]
		public OrchardEncounter Encounter { get; set; }
		
		[CommandProperty(AccessLevel.GameMaster)]
		public VirtueType VirtueType { get; set; }

        [CommandProperty(AccessLevel.GameMaster)]
        public ShadowguardCypressFoilage Foilage { get; set; }

        // 0xD96, 0xD9A, 

        public ShadowguardCypress(OrchardEncounter encounter, VirtueType type)
            : base(3329)
		{
			VirtueType = type;
			Encounter = encounter;

            Foilage = new ShadowguardCypressFoilage(Utility.RandomBool() ? 0xD96 : 0xD9A, this);

			Movable = false;
		}

        public override void OnLocationChange(Point3D oldLocation)
        {
            base.OnLocationChange(oldLocation);

            if (Foilage != null)
                Foilage.Location = new Point3D(X, Y, Z + 6);
        }

        public override void OnMapChange()
        {
            if (Foilage != null)
                Foilage.Map = this.Map;
        }
		
		public override void OnDoubleClick(Mobile from)
		{
			if(from.Backpack != null && from.InRange(this.Location, 3))
			{
                if (Encounter.Apple == null || Encounter.Apple.Deleted)
                {
                    Encounter.Apple = new ShadowguardApple(Encounter, this);
                    from.Backpack.DropItem(Encounter.Apple);

                    Encounter.OnApplePicked();
                }
			}
		}
		
		public bool IsOppositeVirtue(VirtueType type)
		{
			switch(type)
			{
                default:
                case VirtueType.Honesty: return this.VirtueType == VirtueType.Deceit;
                case VirtueType.Compassion: return this.VirtueType == VirtueType.Despise;
                case VirtueType.Valor: return this.VirtueType == VirtueType.Destard;
                case VirtueType.Justice: return this.VirtueType == VirtueType.Wrong;
                case VirtueType.Sacrafice: return this.VirtueType == VirtueType.Covetous;
                case VirtueType.Honor: return this.VirtueType == VirtueType.Shame;
                case VirtueType.Spirituality: return this.VirtueType == VirtueType.Hythloth;
                case VirtueType.Humility: return this.VirtueType == VirtueType.Pride;
                case VirtueType.Deceit: return this.VirtueType == VirtueType.Honesty;
                case VirtueType.Despise: return this.VirtueType == VirtueType.Compassion;
                case VirtueType.Destard: return this.VirtueType == VirtueType.Valor;
                case VirtueType.Wrong: return this.VirtueType == VirtueType.Justice;
                case VirtueType.Covetous: return this.VirtueType == VirtueType.Sacrafice;
                case VirtueType.Shame: return this.VirtueType == VirtueType.Honor;
                case VirtueType.Hythloth: return this.VirtueType == VirtueType.Spirituality;
                case VirtueType.Pride: return this.VirtueType == VirtueType.Humility;
			}
		}
		
		public override void Delete()
		{
			base.Delete();

            if (Foilage != null)
                Foilage.Delete();

			if(Encounter != null)
				Encounter.CheckEncounter();
		}

        public class ShadowguardCypressFoilage : Item
        {
            public ShadowguardCypress Tree { get; set; }

            public ShadowguardCypressFoilage(int id, ShadowguardCypress cypress)
                : base(id)
            {
                Movable = false;
                Tree = cypress;
            }

            public override void OnDoubleClick(Mobile m)
            {
                if (Tree != null)
                    Tree.OnDoubleClick(m);
            }

            public ShadowguardCypressFoilage(Serial serial)
                : base(serial)
            {
            }

            public override void Serialize(GenericWriter writer)
            {
                base.Serialize(writer);
                writer.Write(0);
            }

            public override void Deserialize(GenericReader reader)
            {
                base.Deserialize(reader);
                int version = reader.ReadInt();
            }
        }
    
	
		public ShadowguardCypress(Serial serial) : base(serial)
		{
		}
		
		public override void Serialize(GenericWriter writer)
		{
			base.Serialize(writer);
			writer.Write(0);

            writer.Write(Foilage);
		}

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);
            int version = reader.ReadInt();

            Foilage = reader.ReadItem() as ShadowguardCypressFoilage;

            if (Foilage != null)
            {
                Foilage.Tree = this;
            }
		}
	}
	
	public class Phylactery : BaseDecayingItem
	{
		public override int Lifespan { get { return 60; } }
		public override int LabelNumber { get { return _Purified ? 1156221 : 1156220; } } // Purified Phylactery : Corrupt Phylactery
		
        private bool _Purified;

        [CommandProperty(AccessLevel.GameMaster)]
		public bool Purified
        {
            get { return _Purified; }
            set
            {
                _Purified = value;
                InvalidateProperties();
            }
        }
		
		[Constructable]
		public Phylactery() : base(17076)
		{
            Hue = 2075;
		}
		
		public override void OnDoubleClick(Mobile m)
		{
			if(IsChildOf(m.Backpack))
			{
				m.SendLocalizedMessage(1010086); // What do you want to use this on?
				m.BeginTarget(3, false, Server.Targeting.TargetFlags.None, (from, targeted) =>
				{
					if(targeted is PurifyingFlames)
					{
						var flames = targeted as PurifyingFlames;

                        if (!from.InLOS(flames))
                            from.SendLocalizedMessage(500237); // Target cannot be seen.
                        else if (!Purified)
                        {
                            m.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1156225, m.NetState); // *You purify the phylactery!*

                            Effects.SendLocationParticles(EffectItem.Create(flames.Location, flames.Map, EffectItem.DefaultDuration), 0x3709, 10, 30, 5052);
                            Effects.PlaySound(flames.Location, flames.Map, 0x225); //TODO: Get sound

                            Purified = true;
                            InvalidateProperties();
                        }
					}
					else if (targeted is CursedSuitOfArmor)
					{
						var armor = targeted as CursedSuitOfArmor;

                        if (!from.InLOS(armor))
                            from.SendLocalizedMessage(500237); // Target cannot be seen.
						else if(!_Purified)
							m.SendLocalizedMessage(1156224); // *The cursed armor rejects the phylactery!*
						else
						{
							m.SendLocalizedMessage(1156222); // *You throw the phylactery at the armor causing it to disintegrate!*
							
							Map map = armor.Map;
                            Point3D p;

                            if (armor.ItemID == 5402)
                                p = new Point3D(armor.X - 1, armor.Y, armor.Z);
                            else
                                p = new Point3D(armor.X, armor.Y - 1, armor.Z);

							armor.Delete();
							Delete();
							
							Effects.SendLocationParticles( EffectItem.Create( p, map, EffectItem.DefaultDuration ), 0x3709, 10, 30, 2720, 7, 5052, 0 );
							Effects.PlaySound( p, map, 0x225 ); //TODO: Get sound
							
							Timer.DelayCall(TimeSpan.FromSeconds(1), () =>
							{
								Item item = new Static(Utility.Random(8762, 16));
                                item.Hue = 1111;
                                item.Name = "Broken Armor";
								item.MoveToWorld(p, Map.TerMur);

                                ArmoryEncounter encounter = ShadowguardController.GetEncounter(p, Map.TerMur) as ArmoryEncounter;

								if(encounter != null)
									encounter.AddDestroyedArmor(item);
							
								int ticks = 1;
								Timer.DelayCall(TimeSpan.FromMilliseconds(50), TimeSpan.FromMilliseconds(50), 2, () =>
								{
                                    Server.Misc.Geometry.Circle2D(p, map, ticks, (pnt, mob) =>
									{
										Effects.PlaySound(pnt, mob, 0x307);
										Effects.SendLocationEffect(pnt, mob, Utility.RandomBool() ? 14000 : 14013, 20, 2018, 0);

									});
									
									ticks++;
								});
							});
						}
					}
				});
			}
		}
		
		public Phylactery(Serial serial) : base(serial)
		{
		}
		
		public override void Serialize(GenericWriter writer)
		{
			base.Serialize(writer);
			writer.Write(0);

            writer.Write(_Purified);
		}
		
		public override void Deserialize(GenericReader reader)
		{
			base.Deserialize(reader);
			int version = reader.ReadInt();

            _Purified = reader.ReadBool();
		}
	}
	
	public class CursedSuitOfArmor : Item
	{
		[CommandProperty(AccessLevel.GameMaster)]
		public ShadowguardEncounter Encounter { get; set; }
		
		public override int LabelNumber { get { return 1156218; } } // Cursed Suit of Armor
		
		public CursedSuitOfArmor(ShadowguardEncounter encounter) : base(0x151A)
		{
			Encounter = encounter;
			Movable = false;
		}
		
		public override void Delete()
		{
			base.Delete();
			
			if(Encounter != null)
				Encounter.CheckEncounter();
		}
		
		public CursedSuitOfArmor(Serial serial) : base(serial)
		{
		}
		
		public override void Serialize(GenericWriter writer)
		{
			base.Serialize(writer);
			writer.Write(0);
		}
		
		public override void Deserialize(GenericReader reader)
		{
			base.Deserialize(reader);
			int version = reader.ReadInt();
		}
	}
	
	public class PurifyingFlames : Item
	{
		public override int LabelNumber { get { return 1156217; } } // Purifying Flames
		
        [Constructable]
		public PurifyingFlames() : base(0x19AB)
		{
            Movable = false;
		}
		
		public PurifyingFlames(Serial serial) : base(serial)
		{
		}
		
		public override void Serialize(GenericWriter writer)
		{
			base.Serialize(writer);
			writer.Write(0);
		}
		
		public override void Deserialize(GenericReader reader)
		{
			base.Deserialize(reader);
			int version = reader.ReadInt();
		}
	}
	
	public enum Flow
	{
		EastWest,
        NorthSouth,
		NorthWestCorner,
		NorthEastCorner,
		SouthWestCorner,
		SouthEastCorner
	}
		
	public class ShadowguardCanal : BaseDecayingItem, IChopable
	{
		public override int Lifespan { get { return 1800; } }
		public override int LabelNumber { get { return 1156228; } } // Canal

		private Flow _Flow;
		
		[CommandProperty(AccessLevel.GameMaster)]
        public Flow Flow { get { return _Flow; } set { _Flow = value; InvalideIDfromFlow(); } }
		
        [Constructable]
		public ShadowguardCanal() : base(Utility.RandomList(39911, 39915, 39919, 39924, 39928, 39932))
		{
			InvalidateID();
            Hue = 2500;
		}

        [Constructable]
        public ShadowguardCanal(Flow flow) : base(0)
        {
            Flow = flow;
            Hue = 2500;
        }

        public void OnChop(Mobile from)
        {
            if (Movable)
            {
                Effects.PlaySound(Location, Map, 0x3B3);
                from.SendLocalizedMessage(500461); // You destroy the item.
                Delete();
            }
        }

		public void Fill()
		{
            ItemID--;
            Hue = 0;
		}

        private void InvalideIDfromFlow()
        {
            switch (_Flow)
            {
                case Flow.NorthSouth: ItemID = 39911; break;
                case Flow.SouthEastCorner: ItemID = 39915; break;
                case Flow.SouthWestCorner: ItemID = 39919; break;
                case Flow.EastWest: ItemID = 39924; break;
                case Flow.NorthEastCorner: ItemID = 39928; break;
                case Flow.NorthWestCorner: ItemID = 39932; break;
            }
        }

		private void InvalidateID()
        {
            switch(ItemID)
            {
                default: ItemID = 39911; InvalidateID(); break;
                case 39911: _Flow = Flow.NorthSouth; break;
                case 39915: _Flow = Flow.SouthEastCorner; break;
                case 39919: _Flow = Flow.SouthWestCorner; break;
                case 39924: _Flow = Flow.EastWest; break;
                case 39928: _Flow = Flow.NorthEastCorner; break;
                case 39932: _Flow = Flow.NorthWestCorner; break;
            }
        }

        public bool Connects(ShadowguardCanal next)
        {
            Direction d = Utility.GetDirection(this, next);
            Flow f = next.Flow;

            switch (d)
            {
                case Direction.North:
                    switch (_Flow)
                    {
                        case Flow.EastWest: return false; //
                        case Flow.NorthSouth: return f == Flow.NorthSouth || f == Flow.NorthEastCorner || f == Flow.NorthWestCorner; //
                        case Flow.NorthWestCorner: return false; //
                        case Flow.NorthEastCorner: return false; //
                        case Flow.SouthWestCorner: return f == Flow.NorthSouth || f == Flow.NorthEastCorner || f == Flow.NorthWestCorner; //
                        case Flow.SouthEastCorner: return f == Flow.NorthSouth || f == Flow.NorthEastCorner || f == Flow.NorthWestCorner; //
                    }
                    break;
                case Direction.South:
                    switch (_Flow)
                    {
                        case Flow.EastWest: return false; // 
                        case Flow.NorthSouth: return f == Flow.NorthSouth || f == Flow.SouthEastCorner || f == Flow.SouthWestCorner; //
                        case Flow.NorthWestCorner: return f == Flow.NorthSouth || f == Flow.SouthEastCorner || f == Flow.SouthWestCorner; //
                        case Flow.NorthEastCorner: return f == Flow.NorthSouth || f == Flow.SouthEastCorner || f == Flow.SouthWestCorner; //
                        case Flow.SouthWestCorner: return false; //
                        case Flow.SouthEastCorner: return false; //
                    }
                    break;
                case Direction.East:
                    switch (_Flow)
                    {
                        case Flow.EastWest: return f == Flow.EastWest || f == Flow.NorthEastCorner || f == Flow.SouthEastCorner; //
                        case Flow.NorthSouth: return false; //
                        case Flow.NorthWestCorner: return f == Flow.EastWest || f == Flow.NorthEastCorner || f == Flow.SouthEastCorner; // 
                        case Flow.NorthEastCorner: return false; //
                        case Flow.SouthWestCorner: return f == Flow.EastWest || f == Flow.NorthEastCorner || f == Flow.SouthEastCorner; //
                        case Flow.SouthEastCorner: return false; //
                    }
                    break;
                case Direction.West:
                    switch (_Flow)
                    {
                        case Flow.EastWest: return f == Flow.EastWest || f == Flow.NorthWestCorner || f == Flow.SouthWestCorner; //
                        case Flow.NorthSouth: return false; //
                        case Flow.NorthWestCorner: return false; //
                        case Flow.NorthEastCorner: return f == Flow.EastWest || f == Flow.NorthWestCorner || f == Flow.SouthWestCorner; //
                        case Flow.SouthWestCorner: return false; // 
                        case Flow.SouthEastCorner: return f == Flow.EastWest || f == Flow.NorthWestCorner || f == Flow.SouthWestCorner; //
                    }
                    break;
            }

            return false;
        }
		
		public ShadowguardCanal(Serial serial) : base(serial)
		{
		}
		
		public override void Serialize(GenericWriter writer)
		{
			base.Serialize(writer);
			writer.Write(0);

            writer.Write((int)_Flow);
		}
		
		public override void Deserialize(GenericReader reader)
		{
			base.Deserialize(reader);
			int version = reader.ReadInt();

            _Flow = (Flow)reader.ReadInt();
		}
	}
	
	public class ShadowguardSpigot : Item
	{
		public override int LabelNumber { get { return 1156275; } } // A Spigot
		
		public ShadowguardSpigot(int id) : base(id)  
		{
			Movable = false;
		}
		
		public override void OnDoubleClick(Mobile m)
		{
            FountainEncounter encounter = ShadowguardController.GetEncounter(this.Location, this.Map) as FountainEncounter;

            if (m.InRange(this.Location, 2) && encounter != null && this.ItemID != 17294 && this.ItemID != 17278)
			{
				encounter.UseSpigot(this, m);
			}
		}
		
		public ShadowguardSpigot(Serial serial) : base(serial)
		{
		}
		
		public override void Serialize(GenericWriter writer)
		{
			base.Serialize(writer);
			writer.Write(0);
		}
		
		public override void Deserialize(GenericReader reader)
		{
			base.Deserialize(reader);
			int version = reader.ReadInt();
		}
	}
	
	public class ShadowguardDrain : Item
	{
		public override int LabelNumber { get { return 1156272; } } // A Drain
		
		public ShadowguardDrain() : base(0x9BFF)
		{
			Movable = false;
            Hue = 2500;
		}
		
		public ShadowguardDrain(Serial serial) : base(serial)
		{
		}
		
		public override void Serialize(GenericWriter writer)
		{
			base.Serialize(writer);
			writer.Write(0);
		}
		
		public override void Deserialize(GenericReader reader)
		{
			base.Deserialize(reader);
			int version = reader.ReadInt();
		}
	}
	
	public class MagicDrakeWing : BaseDecayingItem
	{
		public override int Lifespan { get { return 90; } }
		public override int LabelNumber { get { return 1156233; } } // Magic Drake Wing

        [Constructable]
		public MagicDrakeWing() : base(0x1E85)
		{    
		}
		
		public override void OnDoubleClick(Mobile from)
		{
            BelfryEncounter encounter = ShadowguardController.GetEncounter(from.Location, from.Map) as BelfryEncounter;

            if (encounter != null && IsChildOf(from.Backpack))
            {
                Point3D p = encounter.SpawnPoints[1];
                encounter.ConvertOffset(ref p);
                BaseCreature.TeleportPets(from, p, from.Map);
                from.MoveToWorld(p, Map.TerMur);
            }
		}
		
		public MagicDrakeWing(Serial serial) : base(serial)
		{
		}
		
		public override void Serialize(GenericWriter writer)
		{
			base.Serialize(writer);
			writer.Write(0);
		}
		
		public override void Deserialize(GenericReader reader)
		{
			base.Deserialize(reader);
			int version = reader.ReadInt();
		}
	}
	
	public class FeedingBell : BaseAddon
	{
        public override int LabelNumber { get { return 1156232; } }  // Feeding Bell

		[Constructable]
		public FeedingBell()
		{
            AddComponent(new AddonComponent(38955), 0, 0, 0);
            AddComponent(new AddonComponent(38951), 1, 0, 0);
            AddComponent(new LocalizedAddonComponent(19548, 1156232), 0, 0, 0);

            AddComponent(new AddonComponent(3892), 0, 0, 0);
            AddComponent(new AddonComponent(3892), 1, 0, 0);
            AddComponent(new AddonComponent(3893), 0, 1, 0);
            AddComponent(new AddonComponent(3893), 0, 1, 0);
		}

        public override void OnComponentUsed(AddonComponent c, Mobile from)
		{
            if (from.InRange(c.Location, 2) && c.ItemID == 19548)
            {
                BelfryEncounter encounter = ShadowguardController.GetEncounter(c.Location, c.Map) as BelfryEncounter;

                if (encounter != null && encounter.Drakes != null && encounter.Drakes.Count == 0)
                {
                    int toSpawn = 2 + (encounter.PartySize() * 3);

                    for (int i = 0; i < toSpawn; i++)
                    {
                        encounter.SpawnDrake(this.Location, from);
                        Effects.PlaySound(this.Location, this.Map, 0x66C);
                    }
                }
            }
		}
		
		public FeedingBell(Serial serial) : base(serial)
		{
		}
		
		public override void Serialize(GenericWriter writer)
		{
			base.Serialize(writer);
			writer.Write(0);
		}
		
		public override void Deserialize(GenericReader reader)
		{
			base.Deserialize(reader);
			int version = reader.ReadInt();
		}
	}

    public class WitheringBones : Container
    {
        public override int LabelNumber { get { return 1156214; } } // The Withered Bones of an Adventurer
        public override bool IsDecoContainer { get { return false; } }

        [Constructable]
        public WitheringBones()
            : base(0xECF)
        {
            Movable = false;

            DropItem(new TatteredBook());
        }

        public WitheringBones(Serial serial)
            : base(serial)
		{
		}
		
		public override void Serialize(GenericWriter writer)
		{
			base.Serialize(writer);
			writer.Write(0);
		}
		
		public override void Deserialize(GenericReader reader)
		{
			base.Deserialize(reader);
			int version = reader.ReadInt();
		}
    }

    public class TatteredBook : Item
    {
        public override int LabelNumber { get { return 1156215; } } // a tattered book

        public TatteredBook()
            : base(7712)
        {
            Movable = false;
        }

        public override void OnDoubleClick(Mobile m)
        {
            m.SendGump(new InternalGump());
        }

        private class InternalGump : Gump
        {
            public InternalGump()
                : base(100, 150)
            {
                AddBackground(0, 0, 400, 300, 9380);

                AddHtmlLocalized(40, 45, 330, 200, 1156216, 1, false, true);
                /*I've finally found...this vile orchard is the key to Minax's enchantments!...
                 * days I've spent trapped within this tower, I dare not pick the fruit from 
                 * the foliage for I know not what consequences may...Hunger is building...so 
                 * hungry I must...Blech! Vile fruit!...What's this? For when I tossed this 
                 * vile apple from whence it came a horrific beast appeared!...for I hope I 
                 * can fight it...<br>*/
            }
        }

        public TatteredBook(Serial serial)
            : base(serial)
		{
		}
		
		public override void Serialize(GenericWriter writer)
		{
			base.Serialize(writer);
			writer.Write(0);
		}
		
		public override void Deserialize(GenericReader reader)
		{
			base.Deserialize(reader);
			int version = reader.ReadInt();
		}
    }
}
